#include <GameEngine/UnitTest/unit_test.h>

#include <GameEngine/Geometry/Lines/line2d.h>


#ifdef GAMEENGINE_NAMESPACES
namespace GameEngine {
#endif


//! Launch the unit tests on Line2d objects
/*!
 @return True if all unit tests on Line2d objects were
         succesful, false otherwise
 */
template <class T>
bool UnitTest::test_geometry_line2d_functions() {
	bool res = true;

	// Get number of bytes
	MemoryManager::BytesCount bytes = MemoryManager::instance()->bytes();

	// Create line
	GameEngine::Point2d<T> p1((T)0,(T)0);
	GameEngine::Point2d<T> p2((T)1,(T)1);
	GameEngine::Point2d<T> p3((T)0.5,(T)0.5);
	GameEngine::Line2d<T> line(p1,p2);

	// Test points
	T tolerance = (T)0.00001;
	{{
		res &= UNIT_TEST_ERROR( "[Line2d] Test p1()", ( p1.get_square_distance(line.p1()) < tolerance ) );
		res &= UNIT_TEST_ERROR( "[Line2d] Test p2()", ( p2.get_square_distance(line.p2()) < tolerance ) );
		res &= UNIT_TEST_ERROR( "[Line2d] Test operator[]()", ( p1.get_square_distance(line[GameEngine::Line2D::First]) < tolerance ) );
		res &= UNIT_TEST_ERROR( "[Line2d] Test operator[]()", ( p2.get_square_distance(line[GameEngine::Line2D::Second]) < tolerance ) );
	}}

	// Test point function
	{{
		res &= UNIT_TEST_ERROR( "[Line2d] Test point()", ( line.point((T)0.5).get_square_distance(p3) < tolerance ) );
	}}

	// Test intersection function
	{{
		GameEngine::Point2d<T> p4((T)1.5,(T)0.5);
		GameEngine::Line2d<T> line2(p3,p4);
		T coord;
		bool test = ( line.intersection(line2, coord, nil) == GameEngine::IntersectionType::Intersection );
		res &= UNIT_TEST_ERROR( "[Line2d] Test intersection()", test );
		res &= UNIT_TEST_ERROR( "[Line2d] Test intersection()", ( abs(coord-(T)0.5) < tolerance ) );
	}}

	// Test closest point function
	{{
		T coord = line.closest_point(GameEngine::Point2d<T>((T)1,(T)0));
		res &= UNIT_TEST_ERROR( "[Line2d] Test closest_point()", ( abs(coord-(T)0.5) < tolerance ) );
	}}

	// Test degenerate function
	{{
		res &= UNIT_TEST_ERROR( "[Line2d] Test degenerate()", ( line.degenerate() == false ) );
		GameEngine::Line2d<T> line2(p3,p3);
		res &= UNIT_TEST_ERROR( "[Line2d] Test degenerate()", ( line2.degenerate() == true ) );
	}}

	// Get number of bytes
	res &= UNIT_TEST_ERROR( "[Line2d] Test memory leak", ( bytes == MemoryManager::instance()->bytes() ));

	// Return result
	return res;
}


#ifdef GAMEENGINE_NAMESPACES
} // namespace GameEngine
#endif
